#include "QNBCaptureVideoFrame.h"
#include <QCamera>
#ifndef _WINXP
#include <QCameraInfo>
#endif

//added by xuhongneng @20170826 begin

CCaptureVideoFrame::CCaptureVideoFrame(QObject *parent) :
    QAbstractVideoSurface(parent)
{
    m_needsHorizontalMirroring = false;
}

QList<QVideoFrame::PixelFormat> CCaptureVideoFrame::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
    Q_UNUSED(handleType);
    QList<QVideoFrame::PixelFormat> lst;

    //lst.push_back(QVideoFrame::Format_YUYV);//Qt现在不支持此格式，因为Qt内部用了QImage来处理视频帧。
    lst.push_back(QVideoFrame::Format_RGB32);
    lst.push_back(QVideoFrame::Format_BGR32);

    return lst;
}

//捕获视频帧。windows下格式是RGB32；android下是NV21
bool CCaptureVideoFrame::present(const QVideoFrame &frame)
{
    qDebug("CCaptureVideoFrame::present format:%d", frame.pixelFormat());
    emit CaptureFrame(frame);

    return true;
}

//根据不同的平台，设置捕获方式
bool CCaptureVideoFrame::setSource(QCamera *pCamera)
{
    bool ret = true;
    pCamera->setViewfinder(this);

#ifndef _WINXP
    QCameraInfo cameraInfo(*pCamera);
    m_needsHorizontalMirroring = (cameraInfo.position() != QCamera::FrontFace);
    qDebug() << "The camera face of the hardware system is" << cameraInfo.position();
    qDebug() << "The camera sensor orientation is " << cameraInfo.orientation() << " degrees.";
#endif
    return ret;
}

bool notMyFormat(QVideoFrame::PixelFormat pf)
{
   return (pf == QVideoFrame::Format_RGB32 || pf == QVideoFrame::Format_BGR32) ? false : true;
}

void CCaptureVideoFrame::CaptureFrame(const QVideoFrame &frame)
{
    if (notMyFormat(frame.pixelFormat())) {
            setError(IncorrectFormatError);
            return;
        } else {

            QVideoFrame frametodraw(frame);

            if(!frametodraw.map(QAbstractVideoBuffer::ReadOnly))
            {
               setError(ResourceError);
               return;
            }

             //this is a shallow operation. it just refer the frame buffer
             QImage image(
                    frametodraw.bits(),
                    frametodraw.width(),
                    frametodraw.height(),
                    frametodraw.bytesPerLine(),
                    QImage::Format_RGB32);

            m_plbFrame->resize(image.size());

            if(m_needsHorizontalMirroring) {

               QImage mirrored = image.mirrored(true, true);
               //QTransform myTransform;
              // myTransform.rotate(180);
               //QImage  myImage = mirrored.transformed(myTransform);

            //QPixmap::fromImage create a new buffer for the pixmap
               m_plbFrame->setPixmap(QPixmap::fromImage(mirrored));
            } else {
               m_plbFrame->setPixmap(QPixmap::fromImage(image));
            }

            //we can release the data
            frametodraw.unmap();

            m_plbFrame->update();

            return;
        }

    return;
}
